home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * blt2cx07.c - 17-Oct-1995 Cornel Huth
- * This module is called by blt2demo.c
- *
- * Extend Bullet 2 file resources to the max by opening as many files as
- * possible (limited by version level so far as max files/max instances)
- * Filenames generated are based on PID, and so multiple processes can
- * be used without filename conflict. It's recommended that this test be
- * run in a new directory, for no reason other than that you can easily
- * delete the files created, all of which are of the form: $pidnnnn.DBF
- * where pid is the process ID number, and nnnn is the sequence number
- * of the file generated (0001, 0002, onward). (See below at "For Win95...").
- *
- * For non-multi-process versions (Bullet/X), no provision is made for
- * more than one active process (other starts get a 'access denied' or
- * 'file exists' message).
- *
- * No actual add operations are performed in this test (see a later example),
- * but the create/open/close/delete operations are timed.
- *
- * The mix of file types is one index file for each data file. So, if the
- * max files is 100, 50 DBFs and 50 index files are generated; if 250 files
- * then 125/125; for 1024 files, 512 DBFs and 512 index files, though the
- * actual number is determined by the number entered from the keyboard
- * (i.e., the user) and also the DLL capability level -- the shareware
- * DLL has 100 files max, per process, with up to two processes active.
- *
- * ------------------------------------------------------------------------
- * For Win95, VFAT file system, the limit is also like MS-DOS: about 230
- * files. NT using NTFS or HPFS has no preset limit. Also, Win95 seems to
- * return the same PID for things run in an MS-DOS box. This means that if
- * you run this module simultaneously with another "files blowout" run, you
- * should do so in separate directories since the filenames generated are
- * based on the PID, and if the PIDs are the same, so are the filenames.
- * Also, you probably will only be able to open about 230 or so files, tops,
- * on VFAT file systems (i.e., the Win95 file system). This is the maximum
- * *** TOTAL SYSTEM HANDLES *** in Win95/VFAT -- for everything that uses
- * handles (semaphores, files, you name it! only 255 of them system-wide).
- *
- * Bullet95.DLL can open and use up to 100 files at the same time, with up
- * to two concurrent processes.
- *
- * -----------------------------------------------------------------------
- *
- * For DOSX, the file limit is about 250, but is dependent on the FILES=
- * statement in CONFIG.SYS.
- *
- * All files are open simultaneously, i.e., no files are closed until all
- * have been opened, after which all are closed and deleted. The creates,
- * opens, and closes are all timed, individually, as well as the sum of all.
- *
- * Note: Since the process cannot easily know which files belong to it
- * from any previous run, and since there may be multiple processes
- * generating these files, this program deletes the files created
- * at the end of the run, rather than at the beginning as most other
- * examples do.
- *
- * Warning: For FAT file systems, the performance will suffer greatly
- * if a lot of files are requested (say, over 300). This
- * because FAT requires a sequential search through the
- * directory for file opens. (Re: OS/2 FAT, not Win95 VFAT.)
- */
-
- #include "platform.h"
-
- #ifdef ON_OS2
- #define INCL_DOSPROCESS // for OS/2 DosGetInfoBlocks
- #include <os2.h>
- #endif
- #ifdef ON_W95
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #endif
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <string.h>
-
- #ifdef ON_OS2
- #include "bullet2.h"
- #endif
- #ifdef ON_W95
- #include "bullet95.h"
- #endif
- #ifdef ON_DOSX
- #include "bulletx.h"
- #endif
-
- #ifdef ON_OS2
- #define MAX_DATA_FILES 512 // your DLL/LIB may not be capable of allowing
- #define MAX_INDEX_FILES 512 // as many as this (see your manual)
- #endif
- #ifdef ON_W95 // if using NTFS or HPFS, can use more
- #define MAX_DATA_FILES 512 // but VFAT (Win95) is limited to 230 or so
- #define MAX_INDEX_FILES 512 // but NTFS or HPFS under NT can do many more
- #endif
- #ifdef ON_DOSX
- #define MAX_DATA_FILES 125
- #define MAX_INDEX_FILES 125
- #endif
-
- void cx07BuildFieldList(FIELDDESCTYPE fieldList[]);
-
- extern CHAR *collateTable;
-
-
- int cx07(void) {
-
- #pragma pack(1)
-
- DOSFILEPACK DFP;
- CREATEDATAPACK CDP;
- CREATEINDEXPACK CIP;
- HANDLEPACK HP;
- OPENPACK OP;
- QUERYSETPACK QSP;
-
-
- //struct EmpRecType {
- // CHAR tag; // record tag, init to SPACE, * means deleted
- // CHAR empID[9]; // SSN (not 0T string)
- // CHAR empLN[16]; // last name
- // CHAR empFN[16]; // first name
- // CHAR empHire[8]; // "YYYYMMDD" (not 0T string)
- // CHAR empDept[6]; // department assigned
- //}; // 56 bytes
- //struct EmpRecType EmpRec; // not used in this example
-
- #pragma pack()
-
- time_t startTime,endTime,endTime2,endTime3,endTime4,
- endTime5,endTime6,endTime7,endTime8;
-
- LONG rez; // return value from Bullet
- LONG i; // misc counter
-
- LONG maxFiles; // max files DLL allows per process
- LONG userFiles; // number tester wants (up to maxFiles)
- LONG dataFiles; // computed number of data files (1/3rd)
- LONG indexFiles; // computed number of index files (2/3rd)
-
- #ifdef ON_OS2
- PTIB pptib; // for DosGetInfoBlocks
- PPIB pppib; // for DosGetInfoBlocks
- CHAR sPID[4]; // this process ID, ASCII format (e.g.,"0015")
- #endif
- #ifdef ON_W95
- DWORD PID; // process ID (low word only)
- CHAR sPID[4]; // this process ID, ASCII format (e.g.,"0015")
- #endif
-
- CHAR nameData[]="$pid#nnn.DBF"; // data filenames built here
- ULONG dataID[MAX_DATA_FILES]={0}; // handles of data files, max this test uses
- FIELDDESCTYPE fieldList[5]; // 5 fields used in data record (all use same)
-
- CHAR nameIX3[]="$pid#nnn.IX3"; // index filenames built here
- ULONG indexID[MAX_INDEX_FILES]={0}; // handles of indexes, max this test uses
- CHAR keyExpression[128]; // key expression string buffer (all use same)
-
- CHAR tmpStr[64]; // misc stuff, non-Bullet related
-
- setbuf(stdout,NULL);
-
- memset(fieldList,0,sizeof(fieldList)); // init unused bytes to 0 (required)
- cx07BuildFieldList(fieldList);
-
- #ifdef ON_OS2
- // get PID for unique filenames
-
- rez = DosGetInfoBlocks(&pptib,&pppib);
- sprintf(sPID,"%4.4x",(pppib->pib_ulpid & 0xFFFF)); // pre-build filenames
- strncpy(nameData+1,sPID,4);
- strncpy(nameIX3+1,sPID,4);
- #endif
- #ifdef ON_W95
- // get PID for unique filenames
-
- PID = GetCurrentProcessId();
- sprintf(sPID,"%4.4x",(PID & 0xFFFF)); // pre-build filenames ($0001nnn.ext)
- strncpy(nameData+1,sPID,4);
- strncpy(nameIX3+1,sPID,4);
- #endif
-
- // find out max files your DLL/LIB version has (100, 250, or 1024)
- // you'll already know this, but for this general purpose example...
-
- QSP.func = QUERY_SYSVARS_XB;
- QSP.item = 28;
- rez = BULLET(&QSP);
- if (rez) {
- printf("Failed QUERY_SYSVARS call. Err: %li\n",rez);
- goto Abend;
- }
- maxFiles = QSP.itemValue;
-
- #ifdef ON_W95
- printf("** For W95/VFAT: Max files that can be opened is about 230. **\n");
- printf("** That is a SYSTEM-WIDE maximum, not per process. **\n");
- printf("** This includes all handles, not just file handles. **\n");
- #endif
- #ifdef ON_DOSX
- printf("For DOSX: Max files that can be opened is dependent on FILES= in CONFIG.SYS\n");
- #endif
- printf("Max files to generate (half data+half index)? (max %d): ",maxFiles);
- gets(tmpStr);
- userFiles = atol(tmpStr);
- if (userFiles > maxFiles) userFiles = maxFiles;
- if (userFiles < 2) userFiles = 2;
-
- dataFiles = userFiles >> 1; // half are data files
- indexFiles = dataFiles; // and the other half index files
-
- printf("Using %d data and %d index files for a total of %d files\n\n",
- dataFiles,
- indexFiles,
- (dataFiles+indexFiles));
-
- time(&startTime);
-
- // Create the data file, a standard DBF (ID=3) as defined in fieldList above.
-
- CDP.func = CREATE_DATA_XB; // these are all invariant
- CDP.filenamePtr = nameData; // all DBF files will be similar except in name
- CDP.noFields = 5;
- CDP.fieldListPtr = fieldList;
- CDP.fileID = 0x03;
-
- for (i=1;i <= dataFiles;i++) {
-
- sprintf(tmpStr,"%3.3i",i);
- strncpy(nameData+5,tmpStr,3);
-
- rez = BULLET(&CDP);
- if (rez) {
- printf("Failed data file #%i create. Err: %li\n",i,rez);
- goto Abend;
- }
- else
- printf("Created: %d\r",i);
- }
-
- time(&endTime);
- printf("Created: %d data files - took %lu secs.\n",i-1,(endTime - startTime));
-
- // Open the data files
-
- OP.func = OPEN_DATA_XB;
- OP.filenamePtr = nameData;
- OP.asMode = READWRITE | DENYNONE;
-
- for (i=1;i <= dataFiles;i++) {
-
- sprintf(tmpStr,"%3.3i",i);
- strncpy(nameData+5,tmpStr,3);
-
- rez = BULLET(&OP);
- if (rez) {
- printf("Failed data file #%i open. Err: %li\n",i,rez);
- if (rez==4)
- printf("\nYou ran out of handles after %d handles.\n\n",i-1);
- goto Abend;
- }
- else {
- printf(" Opened: %d\r",i);
- dataID[i-1]=OP.handle;
- }
- }
- time(&endTime2);
- printf(" Opened: %d data files - took %lu secs.\n\n",i-1,(endTime2 - endTime));
-
- // Create an index file for each data file.
- // All index files are the same, except for name, for this example
-
- strcpy(keyExpression,"SSN");
-
- CIP.func = CREATE_INDEX_XB;
- CIP.filenamePtr = nameIX3;
- CIP.keyExpPtr = keyExpression;
- CIP.sortFunction = NLS_SORT;
- CIP.codePage = CODEPAGE;
- CIP.countryCode = CTRYCODE;
- CIP.collatePtr = collateTable;
- CIP.nodeSize = 512;
-
- for (i=1;i <= indexFiles;i++) {
-
- sprintf(tmpStr,"%3.3i",i);
- strncpy(nameIX3+5,tmpStr,3);
-
- CIP.xbLink = dataID[i-1]; // its cooresponding DBF handle
- rez = BULLET(&CIP);
- if (rez) {
- printf("Failed index file #%i create. Err: %li\n",i,rez);
- goto Abend;
- }
- else
- printf("Created: %d\r",i);
- }
-
- time(&endTime3);
- printf("Created: %d index files- took %lu secs.\n",i-1,(endTime3 - endTime2));
-
- // Open the index files
-
- OP.func = OPEN_INDEX_XB;
- OP.filenamePtr = nameIX3;
- OP.asMode = READWRITE | DENYNONE;
-
- for (i=1;i <= indexFiles;i++) {
-
- sprintf(tmpStr,"%3.3i",i);
- strncpy(nameIX3+5,tmpStr,3);
-
- OP.xbLink = dataID[i-1]; // its cooresponding DBF handle
- rez = BULLET(&OP);
- if (rez) {
- printf("Failed index file #%i open. Err: %li\n",i,rez);
- if (rez==4)
- printf("\nYou ran out of handles after %d handles.\n\n",dataFiles+i-1);
- goto Abend;
- }
- else {
- printf(" Opened: %d\r",i);
- indexID[i-1]=OP.handle;
- }
- }
- time(&endTime4);
- printf(" Opened: %d index files- took %lu secs.\n\n",i-1,(endTime4 - endTime3));
-
-
- // Abnormal endings come here
- Abend:
-
- if (rez) time(&endTime4);
-
- // Close the index files
-
- HP.func = CLOSE_INDEX_XB;
- for (i=1;i <= indexFiles;i++) {
- if (indexID[i-1]) {
- HP.handle = indexID[i-1];
- rez = BULLET(&HP);
- if (rez)
- printf("Failed index file #%i close. Err: %li\n",i,rez);
- else {
- printf(" Closed: %d\r",i);
- indexID[i-1]=0;
- }
- }
- }
- time(&endTime5);
- printf(" Closed: %d index files- took %lu secs.\n",i-1,(endTime5 - endTime4));
-
- // Close the data files (only closes if handle != 0)
-
- HP.func = CLOSE_DATA_XB;
- for (i=1;i <= dataFiles;i++) {
- if (dataID[i-1]) {
- HP.handle = dataID[i-1];
- rez = BULLET(&HP);
- if (rez)
- printf("Failed data file #%i close. Err: %li\n",i,rez);
- else {
- printf(" Closed: %d\r",i);
- dataID[i-1]=0;
- }
- }
- }
- time(&endTime6);
- printf(" Closed: %d data files - took %lu secs.\n\n",i-1,(endTime6 - endTime5));
-
- // Delete the index files
-
- DFP.func = DELETE_FILE_DOS;
- DFP.filenamePtr = nameIX3;
- for (i=1;i <= indexFiles;i++) {
-
- sprintf(tmpStr,"%3.3i",i);
- strncpy(nameIX3+5,tmpStr,3);
-
- rez = BULLET(&DFP);
- if (rez) {
- printf("Failed index file #%i delete. Err: %li\n",i,rez);
- }
- else
- printf("Deleted: %d index files\r",i);
- }
- time(&endTime7);
- printf("Deleted: %d index files- took %lu secs.\n",i-1,(endTime7 - endTime6));
-
- // Delete the data files
-
- DFP.func = DELETE_FILE_DOS;
- DFP.filenamePtr = nameData;
- for (i=1;i <= dataFiles;i++) {
-
- sprintf(tmpStr,"%3.3i",i);
- strncpy(nameData+5,tmpStr,3);
-
- rez = BULLET(&DFP);
- if (rez) {
- printf("Failed data file #%i delete. Err: %li\n",i,rez);
- }
- else
- printf("Deleted: %d data files\r",i);
- }
- time(&endTime8);
- printf("Deleted: %d data files - took %lu secs.\n\n",i-1,(endTime8 - endTime7));
-
- printf("Total time: %d seconds.\n",(endTime8 - startTime));
- return rez; // module exit
- }
-
-
- //------------------------------------
- // Init field list items for data file
-
- void cx07BuildFieldList(FIELDDESCTYPE fieldList[]) {
-
- strcpy(fieldList[0].fieldName, "SSN"); // field names must be upper-case
- fieldList[0].fieldType = 'C'; // field types must be upper-case
- fieldList[0].fieldLen = 9;
- fieldList[0].fieldDC = 0;
-
- strcpy(fieldList[1].fieldName, "LNAME");
- fieldList[1].fieldType = 'C';
- fieldList[1].fieldLen = 16;
- fieldList[1].fieldDC = 0;
-
- strcpy(fieldList[2].fieldName, "FNAME");
- fieldList[2].fieldType = 'C';
- fieldList[2].fieldLen = 16;
- fieldList[2].fieldDC = 0;
-
- strcpy(fieldList[3].fieldName, "HIRED");
- fieldList[3].fieldType = 'D';
- fieldList[3].fieldLen = 8; // date field type must be 8.0
- fieldList[3].fieldDC = 0;
-
- strcpy(fieldList[4].fieldName, "DEPT");
- fieldList[4].fieldType = 'C';
- fieldList[4].fieldLen = 6;
- fieldList[4].fieldDC = 0;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-